package concurrent;

import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author 26029
 * @date 2025/8/4
 * @description
 */
public class MultiCodeSolutions {
    public static void main(String[] args) {
        ProducerConsumer.print();
    }
}

/**
 * 两个线程一个奇数一个偶数，顺序打印1-100
 */
class PrintOne2HundredOddEven {

    static int count = 100;
    static int now = 1;
    static Semaphore printOdd = new Semaphore(1);
    static Semaphore printEven = new Semaphore(0);

    static public void print() {
        Runnable odd = () -> {
            while (now <= count) {
                try {
                    printOdd.acquire();
                    if (now <= count) {
                        System.out.println(now + " 线程：" + Thread.currentThread());
                        now++;
                    }
                    printEven.release();
                } catch (Exception e) {
                    System.out.println("出错了");
                }
            }
        };

        Runnable even = () -> {
            while (now <= count) {
                try {
                    printEven.acquire();
                    if (now <= count) {
                        System.out.println(now + " 线程：" + Thread.currentThread());
                        now++;
                    }
                    printOdd.release();
                } catch (Exception e) {
                    System.out.println("出错了");
                }
            }
        };

        Thread thread1 = new Thread(odd);
        Thread thread2 = new Thread(even);
        thread1.start();
        thread2.start();
    }
}

/**
 * 三个线程打印1-100，按顺序一个147一个258一个369
 */
class PrintOne2Hundred3Threads {

    static int count = 100;
    static int now = 1;
    static Lock lock = new ReentrantLock(); // 访问 now 的锁
    static Condition condition = lock.newCondition();

    public static void print() {
        Thread t1 = new Thread(() -> printing(1));
        Thread t2 = new Thread(() -> printing(2));
        Thread t3 = new Thread(() -> printing(0));
        t1.start();
        t2.start();
        t3.start();
    }

    private static void printing(int index) {
        while (now <= count) {
            lock.lock();
            try {
                if (now <= count && now % 3 == index) {
                    System.out.println(now + "线程：" + Thread.currentThread());
                    now++;
                    condition.signalAll();
                } else {
                    condition.await();
                }
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            } finally {
                lock.unlock();
            }
        }
    }
}

/**
 * 三个线程ABC顺序打印123，十次
 */
class Print123TenTimes {

    static int count = 30;
    static int now = 1;
    static Lock lock = new ReentrantLock();
    static Condition condition = lock.newCondition();

    public static void print() {
        new Thread(() -> printing(1)).start();
        new Thread(() -> printing(2)).start();
        new Thread(() -> printing(3)).start();
    }

    private static void printing(int printNumber) {
        while (now <= 30) {
            lock.lock();
            try {
                if (now <= 30 && (now - 1) % 3 + 1 == printNumber) {
                    System.out.println(printNumber + " 线程：" + Thread.currentThread());
                    now++;
                    condition.signalAll();
                } else {
                    condition.await();
                }
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            } finally {
                lock.unlock();
            }
        }

    }
}

/**
 * 手撕：生产者-消费者 模式
 */
class ProducerConsumer {

    static Lock lock = new ReentrantLock();
    static Condition notEmpty = lock.newCondition();
    static Condition notFull = lock.newCondition();
    static final int capacity = 10;
    static int now = 0;

    public static void print() {
        Thread t1 = new Thread(() -> produce());
        Thread t2 = new Thread(() -> consume());
        t1.start();
        t2.start();
    }

    private static void produce() {
        while (true) {
            lock.lock();
            try {
                while (now == capacity) {
                    System.out.println("等待不满条件");
                    notFull.await();
                }
                now++;
                System.out.println("生产了一个");
                notEmpty.signal();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            } finally {
                lock.unlock();
            }
        }
    }

    private static void consume() {
        while (true) {
            lock.lock();
            try {
                while (now == 0) {
                    System.out.println("等待不空条件");
                    notEmpty.await();
                }
                now--;
                System.out.println("消费了一个");
                notFull.signal();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            } finally {
                lock.unlock();
            }
        }
    }
}

/**
 * 单例模式
 */
class Singleton {
    private static volatile Singleton instance;

    public static Singleton get() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null)
                    instance = new Singleton();
            }
        }
        return instance;
    }
}